#include "header.hpp"
using namespace std;

// Multiple thread exercise
// Take red envelop
/* Now assume there are ￥100 red envelop, divided to 3 pieces,
 * and there are 5 people try to take it.
 * Red envelop is shared data, 5 people are 5 threads.
 * Simulate the condition by program.
 *
 * Print result:
 * XXX get XXX rmb;
 * XXX get XXX rmb;
 * XXX get XXX rmb;
 * XXX get nothing;
 * XXX get nothing;
*/

//shared data
double money = 100;
int red_envelop_count = 3;
const double MIN = 0.01;
mutex m1;

void take_red_envelop(string name){
    m1.lock();
    if(red_envelop_count == 0){

        cout << name << " get nothing" << endl;
        m1.unlock();

    } else {
        double prize = 0;

        if(red_envelop_count == 1){
            //this is the last one envelop
            //the thread can take all of it
            prize = money;

            printf("%s get %.2lf yuan\n", name.c_str(), prize);

        } else {
            //the first time and the second time
            mt19937 generator(time(NULL));

            uniform_real_distribution<double>
                    turn_on(MIN, money - (red_envelop_count - 1) * MIN);

            double prize = turn_on(generator);

            //take ￥0 is impossible
            if(prize < MIN){
                prize = MIN;
            }

            printf("%s get %.2lf yuan\n", name.c_str(), prize);

            money -= prize;
        }

        red_envelop_count--;

        m1.unlock();
    }
}

void test20(){
    thread t1(take_red_envelop, "alice");
    thread t2(take_red_envelop, "chino");
    thread t3(take_red_envelop, "karen");
    thread t4(take_red_envelop, "yuki");
    thread t5(take_red_envelop, "haruka");

    t1.join();
    t2.join();
    t3.join();
    t4.join();
    t5.join();
}
